The technology described herein relates to a method of and apparatus for processing graphics, and in particular to a method and apparatus for use when processing graphics primitives to generate a render output in a graphics processing system.
Graphics processing is normally carried out by first splitting, e.g. the frame to be displayed, into a number of similar basic components or “primitives”, which primitives are then subjected to the desired graphics processing operations. The graphics “primitives” are usually in the form of simple polygons, such as triangles.
Each primitive is usually defined by and represented as a set of vertices. Each vertex for a primitive has associated with it a set of data (such as position, colour, texture and other attributes data) representing the vertex. This data is then used, e.g., when rasterising and rendering the primitive(s) to which the vertex relates, e.g. for display.
Once primitives and their vertices have been generated and defined, they can be processed by the graphics processing system, in order, e.g., to render the frame.
This process basically involves determining which sampling points of an array of sampling points covering the output area to be processed are covered by a primitive, and then determining the appearance each sampling point should have (e.g. in terms of its colour, etc.) to represent the primitive at that sampling point. These processes are commonly referred to as rasterising and rendering, respectively.
The rasterising process determines the sampling points that should be used for a primitive (i.e. the (x, y) positions of the sample points to be used to represent the primitive in the render output, e.g. frame to be displayed).
The rendering process then derives the data, such as red, green and blue (RGB) colour values and an “Alpha” (transparency) value, necessary to represent the primitive at the sample points (i.e. “shades” each sample point). This can involve, as is known in the art, applying textures, blending sample point data values, etc.
(In 3D graphics literature, the term “rasterisation” is sometimes used to mean both primitive conversion to sample positions and rendering. However, herein “rasterisation” will be used to refer to converting primitive data to sampling point addresses only.)
The rasterisation process basically maps the primitives defining the render output to be generated to the array of sampling points that will be used to render the output. This is typically done by determining, for each sampling point of the render output, whether the sampling point is covered by the primitive in question or not. This determination is typically done by testing the sampling points' positions against the edges of the primitive, to see if the sampling points are covered by the primitive. To do this, graphics processing systems typically derive (line) equations representing each of the edges of a primitive (e.g. using the defined vertices of the primitive), and then test the sampling points' positions using these edge equations. If a sampling point “passes” the edge test, it is taken to be within the primitive.
The rasterisation process is typically carried out by testing sets of one, or of more than one, sampling point. For each set of sampling points found to include a sample point that is covered by the primitive in question (being tested), a discrete graphical entity usually referred to as a “fragment” on which the graphics processing operations (such as rendering) are to be carried out is then generated by the rasteriser and sent to the rest of the graphics processing pipeline (such as the renderer) for processing.
One drawback of current graphics processing systems is that because primitives are processed sequentially, and typically not in perfect front-to-back order, a given sampling point (and hence fragment and pixel) may be shaded multiple-times as an output is processed, e.g. for display. This occurs when a first received and rendered primitive is subsequently covered by a later primitive, such that the rendered first primitive is not in fact seen at the pixel(s) (and sampling point(s)) in question. Primitives can be overwritten many times in this manner and this typically leads to multiple, ultimately redundant, rendering operations being carried out for each render output, e.g. frame, being rendered. This phenomenon is commonly referred to as “overdraw”.
A number of techniques have therefore been proposed to try to reduce the amount of “overdraw” (the amount of redundant processing of hidden surfaces) that is performed when processing a render output, such as a frame for display (i.e. to avoid rendering non-visible primitives and/or fragments, etc.). For example, it is known to carry out forms of hidden surface removal before a primitive and/or fragment is sent for rendering, to see if the primitive or fragment etc. will be obscured by a primitive that has already been rendered (in which case the new fragment and/or primitive need not be rendered). Such hidden surface removal may comprise, for example, early occlusion culling, such as early-Z (depth) and/or stencil, testing processes.
These arrangements try to identify, e.g., sampling points for a new primitive that will be occluded by already processed primitives (and therefore that do not need processing) before the later sampling points are issued to the rendering pipeline. In these arrangements, the depth value, e.g., of a new primitive to be processed at the sampling positions in question is compared to the current depth values for those sampling positions in the depth buffer to see if the new primitive is occluded at the sampling positions in question or not. This can help to avoid sending fragments that are occluded by already processed primitives through the rendering pipeline.
The Applicants have developed a “hierarchical” rasterisation arrangement, in which primitives are iteratively tested against progressively smaller patches (regions) of the render output (target) area (and thus, correspondingly, patches of fragments (and patches of sampling positions)). A primitive to be rasterised is first tested against a larger patch (e.g. a tile in a tile-based graphics processing system) of the render output, to determine if the primitive covers (at least in part) any smaller patches of the render output that the larger patch encompasses. If the primitive does cover (at least in part) any smaller patches of the render output that the larger patch encompasses, then the larger patch is subdivided into those smaller patches, and the process is then repeated for each smaller patch of the render output that was found to be at least partially covered by the primitive, until a minimum patch size is reached.
a. The Applicants believe there remains scope for improvements to the use of hidden surface removal techniques, and in particular early depth testing when using a “hierarchical” rasterisation arrangement.